package com.btpn.custody.bean;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Callable;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Transactional;

import com.btpn.custody.common.Constant;
import com.btpn.custody.dao.IBranch;
import com.btpn.custody.dao.IMasterData;
import com.btpn.custody.dao.ITL_MD;
import com.btpn.custody.entity.Account;
import com.btpn.custody.entity.Branch;
import com.btpn.custody.entity.MasterData;
import com.btpn.custody.entity.TL_MD;
import com.mysql.jdbc.Util;

@Transactional
public class RelateBranchJob implements Callable<HashMap<String, Integer>> {

	private final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass());

	private IMasterData masterDataDaoHibernate;
	private IBranch branchDaoHibernate;
	private ITL_MD TL_MD_DaoHibernate;

	private List<MasterData> masterDatas;
	private int from, to;
	private String user;

	public RelateBranchJob() {
		super();
	}

	public RelateBranchJob(String user, List<MasterData> masterDatas, int from, int to) {
		super();
		this.masterDatas = masterDatas;
		this.from = from;
		this.to = to;
		this.user = user;
	}

	@Override
	public HashMap<String, Integer> call() throws Exception {
		int c_blankCode=0;
		int c_branchNotFound=0;
		int c_related=0;
		int c=0;
		HashMap<String, Integer> result = new HashMap<String, Integer>();

		ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
		if (applicationContext != null) {

			masterDataDaoHibernate = (IMasterData) applicationContext.getBean("masterDataDaoHibernate");
			branchDaoHibernate = (IBranch) applicationContext.getBean("branchDaoHibernate");
			TL_MD_DaoHibernate = (ITL_MD) applicationContext.getBean("TL_MD_DaoHibernate");


			for (int i=from; i<to+1; i++) {

				// Test
				MasterData md = masterDatas.get(i);
				System.out.println(user+" --> "+i+" : "+md.getSid()+" - " + md.getCIF().getBRANCH());

				c++;

				//add by Ozy
				List<Account> lAccount = md.getAccounts();
				Account act= null;
				if (lAccount.size()!=0){
					 act = lAccount.get(0);
				}
				
				System.out.println("===>list Account: "+lAccount.size());
//				System.out.println("===>account branch: "+act.getBRANCH());
//				MasterData md = masterDatas.get(i);
				String theBranch = null;
					theBranch= StringUtils.deleteWhitespace(md.getCIF().getBRANCH());

				// 1. check the branch_code in M_CIF kalo is null or blank?
				if (StringUtils.isBlank(theBranch)||theBranch.isEmpty()||(null==theBranch)||theBranch.equalsIgnoreCase("NULL")) {// code is blank
					logger.info("== EMPTY ==> branch code: "+theBranch+ "account :"+lAccount.size());
					//2. check branch_code di M_ACCOUNT
					if (act != null && act.getBRANCH() !=null ){
						Branch branch = branchDaoHibernate.getByCode(act.getBRANCH());
						// 2. get the branch object
						if (branch == null) {								// branch was not found

							// set STATUS = FAIL
							md.setSTATUS_MD(Constant.STATUS__MD_FAIL);
							md.setUpdatedBy(user);
							md.setUpdatedDate(new Date());

							c_branchNotFound++;
							logger.warn("{}. MD[{}] with Branch[{}] : branch not found", new Object[] {c, md.getSid(), theBranch});	//md.getCIF().getCifSid()
							logger.info("get M_ACCOUNT code_branch {} with Branch[{}]", act.getBRANCH(), theBranch );
							logger.info("===> gagal account branch_code: "+act.getBRANCH());
						} else {																			// relate branch with MasterData
							// set branch
							md.setBranch(branch);

							// set STATUS = INIT
							md.setSTATUS_MD(Constant.STATUS__MD_NPY);
							md.setUpdatedBy(user);
							md.setUpdatedDate(new Date());

							// add to TL_MD
							TL_MD tl_MD = new TL_MD(Constant.ACTION__CREATE, md.getBranch().getCode() + Constant.STRIP + user,
									md.getSid() + Constant.STRIP + md.getCIF().getCifSid(), Constant.STATUS__MD_NEW + Constant.ARROW_RIGHT + Constant.STATUS__MD_NPY);
							TL_MD_DaoHibernate.create(tl_MD);

							c_related++;
							logger.info("{}. Related MD[{}] with Branch[{}]", new Object[] {c, md.getCIF().getCifSid(), theBranch});
							logger.info("{}. Related MD[{}] with Branch[{}]", new Object[] {c, md.getCIF().getCifSid(), branch.getName()});
							logger.info("=====set branch berhasil account branch_code: "+act.getBRANCH());
						}

					}else{ // jika tidak ketemu di M_ACCOUNT --> set STATUS = FAIL
						md.setSTATUS_MD(Constant.STATUS__MD_FAIL);
						md.setUpdatedBy(user);
						md.setUpdatedDate(new Date());

						c_blankCode++;
						logger.warn("{}. MD[{}] has blank branchCode", c, md.getSid());						// md.getCIF().getCifSid()
						logger.info("not found in M_ACCOUNT size {}.  ", lAccount.size());
					}
				} else {// code is not blank
					logger.info("== NOT EMPY ==> "+theBranch);
					Branch branch = branchDaoHibernate.getByCode(theBranch);

					// 2. get the branch object
					if (branch == null) {								// branch was not found

						// set STATUS = FAIL
						md.setSTATUS_MD(Constant.STATUS__MD_FAIL);
						md.setUpdatedBy(user);
						md.setUpdatedDate(new Date());

						c_branchNotFound++;
						logger.warn("{}. MD[{}] with Branch[{}] : branch not found", new Object[] {c, md.getSid(), theBranch});	//md.getCIF().getCifSid()
					} else {																			// relate branch with MasterData

						// set branch
						md.setBranch(branch);

						// set STATUS = INIT
						md.setSTATUS_MD(Constant.STATUS__MD_NPY);
						md.setUpdatedBy(user);
						md.setUpdatedDate(new Date());

						// add to TL_MD
						TL_MD tl_MD = new TL_MD(Constant.ACTION__CREATE, md.getBranch().getCode() + Constant.STRIP + user,
								md.getSid() + Constant.STRIP + md.getCIF().getCifSid(), Constant.STATUS__MD_NEW + Constant.ARROW_RIGHT + Constant.STATUS__MD_NPY);
						TL_MD_DaoHibernate.create(tl_MD);

						c_related++;
						logger.info("{}. Related MD[{}] with Branch[{}]", new Object[] {c, md.getCIF().getCifSid(), theBranch});
					}
				}

				masterDataDaoHibernate.merge(md);
			}
		}

		result.put("c_blankCode", c_blankCode);
		result.put("c_branchNotFound", c_branchNotFound);
		result.put("c_related", c_related);
		result.put("c", c);
		return result;
	}
}
